package com.xiaoxi.exam.service;

import cn.xinzhili.xutils.core.ErrorCode;
import cn.xinzhili.xutils.core.FailureException;
import cn.xinzhili.xutils.core.util.HashUtils;
import com.aliyuncs.exceptions.ClientException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.xiaoxi.exam.bean.ExamOrderInfo;
import com.xiaoxi.exam.bean.OrderInfo;
import com.xiaoxi.exam.bean.OrderInfoDetail;
import com.xiaoxi.exam.bean.VerifyCodeBean;
import com.xiaoxi.exam.bean.enums.OrderStatus;
import com.xiaoxi.exam.bean.enums.WxPayRequestStatus;
import com.xiaoxi.exam.bean.errorcode.OrderErrorCode;
import com.xiaoxi.exam.bean.errorcode.UserErrorCode;
import com.xiaoxi.exam.bean.request.AddOrderRequest;
import com.xiaoxi.exam.bean.request.BaseOrderRequest;
import com.xiaoxi.exam.bean.request.UpdateOrderRequest;
import com.xiaoxi.exam.bean.request.WxPayResultNotifyRequest;
import com.xiaoxi.exam.bean.response.OrderInfoResponse;
import com.xiaoxi.exam.bean.response.WxPayResponse;
import com.xiaoxi.exam.bean.response.WxPayResultNotifyResponse;
import com.xiaoxi.exam.config.XiaoxiWXAccountConfig;
import com.xiaoxi.exam.consts.Const;
import com.xiaoxi.exam.dao.PreOrderMapper;
import com.xiaoxi.exam.dao.ToeflOrderMapper;
import com.xiaoxi.exam.dao.ToeflSchoolMapper;
import com.xiaoxi.exam.model.PreOrder;
import com.xiaoxi.exam.model.PreOrderExample;
import com.xiaoxi.exam.model.ToeflOrder;
import com.xiaoxi.exam.model.ToeflOrderExample;
import com.xiaoxi.exam.model.ToeflSchool;
import com.xiaoxi.exam.model.ToeflSchoolExample;
import com.xiaoxi.exam.model.User;
import com.xiaoxi.exam.utils.DateUtils;
import com.xiaoxi.exam.utils.JsonUtils;
import com.xiaoxi.exam.utils.OrderUtils;
import com.xiaoxi.exam.utils.SmsUtil;
import com.xiaoxi.exam.utils.UserFactory;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
@Slf4j
public class OrderService {

  DateTimeFormatter examDf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

  @Autowired
  private UserService userService;
  @Autowired
  private XiaoxiWXAccountConfig accountConfig;
  @Autowired
  private PreOrderMapper preOrderMapper;
  @Autowired
  private ToeflOrderMapper toeflOrderMapper;
  @Autowired
  private ToeflSchoolMapper toeflSchoolMapper;
  private static ClassPathResource CPR = new ClassPathResource("cert/apiclient_cert.p12");


  @Value("${app.sms.code.verify:SMS_151910361}")
  private String verifyTemplateCode;

  private static final ObjectMapper mapper = new ObjectMapper();


  @Transactional
  public WxPayResponse preOrder(AddOrderRequest request) {
    checkOrderRequest(request);
    User userInfo = userService.getExistUser(request.getOpenId());
    List<PreOrder> preOrders = getOrderByVerifyCode(request.getVerifyCode(), request.getPhone(),
        HashUtils.decode(request.getPreId()), userInfo);
    deleteRepeatOrder(request);
    PreOrder tempOrder = preOrders.get(0);
    String orderNo;
    if (StringUtils.isEmpty(tempOrder.getTradeNo())) {
      orderNo = OrderUtils.genTradeNo(HashUtils.encode(userInfo.getId()), request.getType(),
          HashUtils.encode(tempOrder.getId()));
    } else {
      orderNo = tempOrder.getTradeNo();
    }
    String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
    Map<String, String> pay = pay(request.getOpenId(), orderNo, Const.FEE_MAP.get("TOEFL_FEE"));
    WxPayResponse response = new WxPayResponse();
    if ("SUCCESS".equals(pay.get("return_code"))) {
      Map<String, String> reData = new HashMap<>();
      reData.put("appId", accountConfig.getAppID());
      reData.put("nonceStr", pay.get("nonce_str"));
      String newPackage = "prepay_id=" + pay.get("prepay_id");
      reData.put("package", newPackage);
      reData.put("signType", "MD5");
      reData.put("timeStamp", timeStamp);
      String newSign;
      try {
        newSign = WXPayUtil.generateSignature(reData, accountConfig.getKey());
        response.setPaySign(newSign);
      } catch (Exception e) {
        e.printStackTrace();
        throw new FailureException(OrderErrorCode.PRE_ORDER_ERROR);
      }
    }
    response.setAppId(accountConfig.getAppID());
    response.setNonceStr(pay.get("nonce_str"));
    response.setPackageStr("prepay_id=" + pay.get("prepay_id"));
    response.setSignType("MD5");
    response.setTimeStamp(timeStamp);

    tempOrder.setTradeNo(orderNo);
    tempOrder.setOrderTime(LocalDateTime.now());

    insertToeflExams(request.getOrderInfos(), tempOrder.getId(), request.getPhone(),
        userInfo.getId(), orderNo);

    tempOrder.setStatus((short) 1);//下单状态 待支付
    preOrderMapper.updateByPrimaryKey(tempOrder);
    response.setOrderId(HashUtils.encode(tempOrder.getId()));
    return response;
  }

  /**
   * 防止生成重复订单
   */
  private void deleteRepeatOrder(AddOrderRequest request) {
    ToeflOrderExample deleteExample = new ToeflOrderExample();
    deleteExample.or().andOrderIdEqualTo(HashUtils.decode(request.getPreId()));
    toeflOrderMapper.deleteByExample(deleteExample);
  }

  private List<PreOrder> getOrderByVerifyCode(String verifyCode, String phone, Long orderId,
      User userInfo) {
    PreOrderExample preOrderExample = new PreOrderExample();
    preOrderExample.or().andCodeEqualTo(verifyCode).andPhoneEqualTo(phone)
        .andIdEqualTo(orderId).andDeletedAtIsNull()
        .andUserIdEqualTo(userInfo.getId());
    List<PreOrder> preOrders = preOrderMapper.selectByExample(preOrderExample);
    if (preOrders.isEmpty()) {
      throw new FailureException(OrderErrorCode.VERIFY_CODE_ERROR);
    }
    return preOrders;
  }

  public List<OrderInfo> getOrderByUserId(Long id) {
    PreOrderExample preOrderExample = new PreOrderExample();
    preOrderExample.or().andUserIdEqualTo(id).andStatusIn(OrderStatus.getShowOrderList())
        .andDeletedAtIsNull();
    preOrderExample.setOrderByClause("created_at desc");
    List<PreOrder> preOrders = preOrderMapper.selectByExample(preOrderExample);
    List<OrderInfo> result = preOrders.stream().map(po -> {
      ToeflOrderExample example = new ToeflOrderExample();
      example.or().andOrderIdEqualTo(po.getId());
      example.setOrderByClause("created_at desc");
      List<ToeflOrder> toeflOrders = toeflOrderMapper.selectByExample(example);
      OrderInfo orderInfo = new OrderInfo();
      if (!toeflOrders.isEmpty()) {
        ToeflOrder toeflOrder = toeflOrders.get(0);
        List<String> dates = toeflOrders.stream()
            .filter(t -> Objects.equals(toeflOrder.getCity(), t.getCity())).map(ToeflOrder::getDate)
            .distinct()
            .collect(Collectors.toList());
        orderInfo.setExamTime(dates);
        orderInfo.setExamCity(toeflOrder.getCity());
        orderInfo.setExamSchool(
            toeflOrders.stream().filter(t -> Objects.equals(toeflOrder.getCity(), t.getCity()))
                .map(ToeflOrder::getSchool).distinct()
                .collect(Collectors.toList()));
        if (po.getStatus() == OrderStatus.ORDER_SUCCESS.getCode()) {
          Optional<ToeflOrder> first = toeflOrders.stream().filter(to -> to.getStatus() == 1)
              .findFirst();
          first.ifPresent(to -> orderInfo.setSuccessSchool(to.getSchool()));
        }
      }
      orderInfo.setStatus(OrderStatus.getStatus(po.getStatus()));
      orderInfo.setId(HashUtils.encode(po.getId()));
      return orderInfo;
    }).collect(Collectors.toList());
    return result;
  }

  public Map<String, String> pay(String openId, String tradeNo, String fee) {
    WXPay wxpay = new WXPay(accountConfig);
    Map<String, String> data = new HashMap<String, String>();
    data.put("appid", accountConfig.getAppID());
    data.put("mch_id", accountConfig.getMchID());
    data.put("nonce_str", WXPayUtil.generateNonceStr());
    data.put("openid", openId);
    data.put("fee_type", "CNY");
    data.put("device_info", "WEB");
    data.put("body", "小西考位代报");
    data.put("out_trade_no", tradeNo);
    data.put("total_fee", String.valueOf(Integer.valueOf(fee) * 100));
    data.put("spbill_create_ip", "127.0.0.1");
    data.put("notify_url", "https://api.zhiganglan.com/notify/wx");
    data.put("trade_type", "JSAPI");
    try {
      return wxpay.unifiedOrder(data);
    } catch (Exception e) {
      log.error("wechat pay failed, data: {}, error message: {}", data, e.getMessage());
      throw new FailureException(ErrorCode.REQUEST_FAILED);
    }
  }

  public OrderInfoResponse getOrderDetailById(long orderId) {
    PreOrder preOrder = preOrderMapper.selectByPrimaryKey(orderId);
    if (Objects.nonNull(preOrder)) {
      OrderInfoDetail orderInfo = new OrderInfoDetail();
      orderInfo.setId(HashUtils.encode(orderId));
      orderInfo.setStatus(OrderStatus.getStatus(preOrder.getStatus()));
      ToeflOrderExample example = new ToeflOrderExample();
      example.or().andOrderIdEqualTo(orderId);
      example.setOrderByClause("created_at desc");
      List<ToeflOrder> toeflOrders = toeflOrderMapper.selectByExample(example);
      if (!toeflOrders.isEmpty()) {
        ToeflOrder toeflOrder = toeflOrders.get(0);
        List<String> dates = toeflOrders.stream()
            .filter(t -> Objects.equals(toeflOrder.getCity(), t.getCity())).map(ToeflOrder::getDate)
            .distinct()
            .collect(Collectors.toList());
        if (preOrder.getStatus() == OrderStatus.ORDER_SUCCESS.getCode()) {
          Optional<ToeflOrder> first = toeflOrders.stream().filter(to -> to.getStatus() == 1)
              .findFirst();
          first.ifPresent(to -> {
            orderInfo.setSuccessSchool(to.getSchool());
            orderInfo.setSuccessDate(to.getDate());
          });
        }
        ToeflSchoolExample toeflSchoolExample = new ToeflSchoolExample();
        toeflSchoolExample.createCriteria().andCityEqualTo(toeflOrder.getCity())
            .andDeletedAtIsNull();
        List<ToeflSchool> toeflSchools = toeflSchoolMapper.selectByExample(toeflSchoolExample);
        if (!toeflSchools.isEmpty()) {
          orderInfo.setExamProvince(toeflSchools.get(0).getProvince());
        }
        orderInfo.setFee(preOrder.getTotalAmount() / 100 + "."
            + preOrder.getTotalAmount() % 100);
        orderInfo.setOrderNo(preOrder.getTradeNo());
        orderInfo.setPayTime(
            Objects.nonNull(preOrder.getPayTime()) ? preOrder.getPayTime().format(examDf)
                : LocalDateTime.now().format(examDf));
        orderInfo.setExamTime(dates);
        orderInfo.setExamCity(toeflOrder.getCity());
        orderInfo.setExamSchool(
            toeflOrders.stream().filter(t -> Objects.equals(toeflOrder.getCity(), t.getCity()))
                .map(ToeflOrder::getSchool).distinct()
                .collect(Collectors.toList()));
      }
      OrderInfoResponse response = new OrderInfoResponse();
      response.setOrderDetail(orderInfo);
      return response;
    }
    throw new FailureException(OrderErrorCode.ORDER_NOT_FOUND);
  }

  public String getVerifyCode(String openId, String phone, String orderId) {
    User userInfo = userService.getUserInfo(openId);
    if (Objects.isNull(userInfo)) {
      throw new FailureException(UserErrorCode.USER_NOT_EXIST);
    }
    if (Objects.isNull(orderId)) {
      PreOrder preOrder = new PreOrder();
      preOrder.setUserId(userInfo.getId());
      preOrder.setPhone(phone);
      preOrder.setCode(UserFactory.getVerifyCode());
      preOrder.setStatus((short) 0);// 0 发送验证码
      preOrder.setTotalAmount((int) (Double.valueOf(Const.FEE_MAP.get("TOEFL_FEE")) * 100));
      long id = preOrderMapper.insertReturningId(preOrder);
      VerifyCodeBean bean = new VerifyCodeBean();
      bean.setCode(preOrder.getCode());
      sendVerifyCode(bean, phone, userInfo.getId());
      return HashUtils.encode(id);
    } else {
      PreOrder preOrder = new PreOrder();
      preOrder.setId(HashUtils.decode(orderId));
      preOrder.setCode(UserFactory.getVerifyCode());
      preOrderMapper.updateByPrimaryKeySelective(preOrder);
      VerifyCodeBean bean = new VerifyCodeBean();
      bean.setCode(preOrder.getCode());
      sendVerifyCode(bean, phone, userInfo.getId());
      return orderId;
    }
  }

  public void sendVerifyCode(VerifyCodeBean verifyCodeBean, String mobile, long userId) {
    try {
      SmsUtil.sendSms(mobile, verifyTemplateCode,
          mapper.writeValueAsString(verifyCodeBean));
    } catch (ClientException e) {
      log.warn("send message failed! mobile:{}, openId:{}", mobile, userId);
      throw new FailureException(UserErrorCode.VERIFY_CODE_SEND_FAILED);
    } catch (JsonProcessingException e) {
      log.warn(e.getMessage());
      throw new FailureException(ErrorCode.REQUEST_FAILED);
    }
  }

  @Transactional
  public void userCancelOrder(long id, long userId) {
    PreOrderExample preOrderExample = new PreOrderExample();
    preOrderExample.or().andIdEqualTo(id).andUserIdEqualTo(userId).andDeletedAtIsNull();
    List<PreOrder> preOrders = preOrderMapper.selectByExample(preOrderExample);
    if (preOrders.isEmpty()) {
      throw new FailureException(OrderErrorCode.ORDER_NOT_FOUND);
    }
    PreOrder preOrder = preOrders.get(0);
    preOrder.setStatus((short) OrderStatus.USER_CANCEL.getCode());
    preOrderMapper.updateByPrimaryKey(preOrder);
    ToeflOrderExample toeflOrderExample = new ToeflOrderExample();
    toeflOrderExample.createCriteria().andOrderIdEqualTo(preOrder.getId());
    toeflOrderMapper.deleteByExample(toeflOrderExample);
    WXRefund(preOrder);
//    syncService.deleteOrder(id);
  }

  private void WXRefund(PreOrder preOrder) {
    Map<String, String> reqData = new HashMap<>();
    //商户退款单号
    reqData.put("out_refund_no", preOrder.getTradeNo());
    //商户订单号
    reqData.put("out_trade_no", preOrder.getTradeNo());
    reqData.put("total_fee", preOrder.getTotalAmount().toString());
    reqData.put("refund_fee", preOrder.getTotalAmount().toString());

    Map<String, String> refundResult;
    try (InputStream inputStream = CPR.getInputStream()) {
      accountConfig.setCertBis(inputStream);
      WXPay wxPay = new WXPay(accountConfig);
      refundResult = wxPay.refund(reqData);
      if (Objects.nonNull(refundResult.get("result_code")) && "SUCCESS"
          .equals(refundResult.get("result_code"))) {
        log.info(
            "********************** wechat refund request send success **************************");
        log.info("* out_trade_no: {}", refundResult.get("out_trade_no"));
        log.info("* transaction_id: {}", refundResult.get("transaction_id"));
        log.info("* refund_fee_0: {}", refundResult.get("refund_fee_0"));
        log.info("* refund_status_0: {}", refundResult.get("refund_status_0"));
        log.info("*******************************************************************");
      } else {
        log.warn("refund failed, message is : {}", refundResult);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public WxPayResultNotifyResponse handleWXNotify(WxPayResultNotifyRequest request) {
    log.info("wx notify start...................");
    log.info("wx notify request.................{}", JsonUtils.toJson(request));

    WxPayResultNotifyResponse response = new WxPayResultNotifyResponse();
    PreOrder order = getOrderByOutTradeNo(request.getOut_trade_no());
    log.info("wx notify order...................{}", JsonUtils.toJson(order));

    if (Objects.isNull(order)) {
      log.error("no unpay order found");
      response.setReturn_code(WxPayRequestStatus.FAIL);
      return response;
    }

    if (wxPaidValid(order, request)) {
      updateOrderSuccess(order, request.getTime_end(), request.getTransaction_id());
      response.setReturn_code(WxPayRequestStatus.SUCCESS);
//      syncService.syncOrder(order.getId());
    } else {
      log.error("wx pay fail ! {},{}", request, order);
      response.setReturn_code(WxPayRequestStatus.FAIL);
    }
    return response;
  }

  private void updateOrderSuccess(PreOrder order, String timeEnd, String transactionId) {
    order.setStatus((short) 2);
    order.setPayTime(DateUtils.formatter(timeEnd));
    preOrderMapper.updateByPrimaryKey(order);

  }

  private boolean wxPaidValid(PreOrder order, WxPayResultNotifyRequest payResultNotify) {

    boolean isSuccess = wxPaidSuccess(payResultNotify);
    boolean signValid = payResultNotify.signValid(accountConfig.getKey());
    boolean free = order.getTotalAmount() == payResultNotify.getTotal_fee();
    log.info("order money : {}, notify money : {}", order.getTotalAmount(),
        payResultNotify.getTotal_fee());
    log.info("wx notify .............{},{},{}", isSuccess, signValid, free);
    return isSuccess && signValid;
  }

  private boolean wxPaidSuccess(WxPayResultNotifyRequest notifyRequest) {
    return notifyRequest.isContact() && notifyRequest.isSuccess();
  }

  private PreOrder getOrderByOutTradeNo(String outTradeNo) {
    PreOrderExample example = new PreOrderExample();
    example.or().andTradeNoEqualTo(outTradeNo).andDeletedAtIsNull().andStatusEqualTo((short) 1);
    List<PreOrder> preOrders = preOrderMapper.selectByExample(example);
    if (preOrders.isEmpty()) {
      return null;
    }
    return preOrders.get(0);
  }

  @Transactional
  public void updateOrder(UpdateOrderRequest request) {
    User user = userService.getExistUser(request.getOpenId());
    Long orderId = HashUtils.decode(request.getOrderId());
    ToeflOrderExample example = new ToeflOrderExample();
    example.createCriteria().andOrderIdEqualTo(orderId).andDeletedAtIsNull();
    toeflOrderMapper.deleteByExample(example);
    List<PreOrder> preOrders = getOrderByVerifyCode(request.getVerifyCode(), request.getPhone(),
        HashUtils.decode(request.getOrderId()), user);
    if (!preOrders.isEmpty()) {
      insertToeflExams(request.getOrderInfos(), orderId, request.getPhone(), user.getId(),
          preOrders.get(0).getTradeNo());
    }
  }

  private void insertToeflExams(List<ExamOrderInfo> exams, Long orderId, String phone, Long userId,
      String orderNo) {
    exams.forEach(info -> info.getDate().forEach(date -> {
          ToeflOrder toeflOrder = new ToeflOrder();
          toeflOrder.setDate(date);
          toeflOrder.setSortNo(info.getOrder());
          toeflOrder.setOrderId(orderId);
          toeflOrder.setPhone(phone);
          toeflOrder.setStatus(0);
          toeflOrder.setUserId(userId);
          toeflOrder.setTradeNo(orderNo);
          toeflOrder.setSchool(info.getSchool());
          toeflOrder.setCity(info.getCity());
          toeflOrderMapper.insert(toeflOrder);
        }
    ));
  }

  private void checkOrderRequest(BaseOrderRequest request) {
    if (request.getOrderInfos().isEmpty()) {
      throw new FailureException(ErrorCode.INVALID_PARAMS);
    }
  }

  public void expireRefund() {
    PreOrderExample example = new PreOrderExample();
    example.createCriteria().andStatusIn(OrderStatus.getRefundStatus()).andDeletedAtIsNull();
    List<PreOrder> preOrders = preOrderMapper.selectByExample(example);
    preOrders.forEach(this::WXRefund);
  }

  public List<PreOrder> getNeedBookOrder() {
    PreOrderExample example = new PreOrderExample();
    example.createCriteria().andDeletedAtIsNull().andStatusEqualTo((short) 2);
    return preOrderMapper.selectByExample(example);
  }

  public List<ToeflOrder> getToeflOrderListByOrderId(Long id) {
    ToeflOrderExample example = new ToeflOrderExample();
    example.createCriteria().andOrderIdEqualTo(id).andDeletedAtIsNull();
    example.setOrderByClause("sort_no asc");
    return toeflOrderMapper.selectByExample(example);
  }


  public long totalEnablePreorders() {
    PreOrderExample example = new PreOrderExample();
    example.createCriteria().andStatusEqualTo((short) 2).andDeletedAtIsNull();
    return preOrderMapper.countByExample(example);
  }

  public List<OrderInfo> getPreorderLists(int pageAt, int pageSize) {
    List<PreOrder> orders = getPreOrders(pageAt, pageSize);
    return orders.stream().map(order -> {
      OrderInfo orderInfo = new OrderInfo();
      List<ToeflOrder> toeflOrders = getToeflOrderListByOrderId(order.getId()).stream()
          .filter(to -> DateUtils.getExamDate(to.getDate().split(" ")[0]).isAfter(LocalDate.now()))
          .collect(Collectors.toList());
      if (toeflOrders.isEmpty()) {
        return orderInfo;
      }
      ToeflOrder tempToeflOrder = toeflOrders.get(0);
      orderInfo.setId(HashUtils.encode(order.getId()));
      orderInfo.setExamCity(tempToeflOrder.getCity());
      orderInfo.setExamSchool(
          toeflOrders.stream().map(ToeflOrder::getSchool).collect(Collectors.toList()));
      orderInfo
          .setExamTime(toeflOrders.stream().map(ToeflOrder::getDate).collect(Collectors.toList()));
      orderInfo.setUId(order.getUserId());
      orderInfo.setTel(order.getPhone());
      return orderInfo;
    }).collect(Collectors.toList());
  }

  private List<PreOrder> getPreOrders(int pageAt, int pageSize) {
    PreOrderExample example = new PreOrderExample();
    example.createCriteria().andStatusEqualTo((short) 2).andDeletedAtIsNull();
    example.setLimit(pageSize);
    example.setOffset(pageAt * pageSize);
    return preOrderMapper.selectByExample(example);
  }

  @Transactional
  public void orderSuccess(long orderId, String school, String date, Long detailId) {
    PreOrder preOrder = preOrderMapper.selectByPrimaryKey(orderId);
    if (Objects.nonNull(preOrder)) {
      preOrder.setStatus((short) 3);
      preOrderMapper.updateByPrimaryKey(preOrder);
      ToeflOrderExample example = new ToeflOrderExample();
      example.createCriteria().andOrderIdEqualTo(orderId).andIdEqualTo(detailId);
      List<ToeflOrder> toeflOrders = toeflOrderMapper.selectByExample(example);
      if (!toeflOrders.isEmpty()) {
        ToeflOrder toeflOrder = toeflOrders.get(0);
        toeflOrder.setStatus(1);
        ToeflOrderExample example1 = new ToeflOrderExample();
        example1.createCriteria().andIdEqualTo(toeflOrder.getId()).andDeletedAtIsNull();
        toeflOrderMapper.updateByExample(toeflOrder, example1);
      }
    }
  }
}
